home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / editors / mjovesrc.zoo / abbrev.c next >
C/C++ Source or Header  |  1992-04-04  |  6KB  |  293 lines

  1. /***************************************************************************
  2.  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  3.  * is provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is    *
  5.  * included in all the files.                                              *
  6.  ***************************************************************************/
  7.  
  8. #include "jove.h"
  9.  
  10. #ifdef    ABBREV
  11.  
  12. #include "fp.h"
  13. #include "ctype.h"
  14.  
  15. #ifdef    MSDOS
  16. # include <io.h>
  17. #endif
  18. #define HASHSIZE    20
  19.  
  20. struct abbrev {
  21.     unsigned int    a_hash;
  22.     char    *a_abbrev,
  23.         *a_phrase;
  24.     struct abbrev    *a_next;
  25.     data_obj    *a_cmdhook;
  26. };
  27.  
  28. private    void
  29.     define proto((struct abbrev **, char *, char *));
  30.  
  31. #define GLOBAL    NMAJORS
  32. private struct abbrev    *A_tables[NMAJORS + 1][HASHSIZE];    /* Must be zeroed! */
  33.  
  34. bool AutoCaseAbbrev = ON;
  35.  
  36. private unsigned int
  37. hash(a)
  38. register char    *a;
  39. {
  40.     register unsigned int    hashval = 0;
  41.     register int    c;
  42.  
  43.     while ((c = *a++) != '\0')
  44.         hashval = (hashval << 2) + c;
  45.  
  46.     return hashval;
  47. }
  48.  
  49. private void
  50. def_abbrev(table)
  51. struct abbrev    *table[HASHSIZE];
  52. {
  53.     char    abbrev[100],
  54.         phrase[100];
  55.  
  56.     null_ncpy(abbrev, ask((char *)NULL, "abbrev: "), sizeof(abbrev)-1);
  57.     null_ncpy(phrase, ask((char *)NULL, "abbrev: %s phrase: ", abbrev),
  58.         sizeof(phrase)-1);
  59.     define(table, abbrev, phrase);
  60. }
  61.  
  62. private struct abbrev *
  63. lookup_abbrev(table, abbrev)
  64. register struct abbrev    *table[HASHSIZE];
  65. register char    *abbrev;
  66. {
  67.     register struct abbrev    *ap;
  68.     unsigned int    h;
  69.  
  70.     h = hash(abbrev);
  71.     for (ap = table[h % HASHSIZE]; ap; ap = ap->a_next)
  72.         if (ap->a_hash == h && strcmp(ap->a_abbrev, abbrev) == 0)
  73.             break;
  74.     return ap;
  75. }
  76.  
  77. private void
  78. define(table, abbrev, phrase)
  79. register struct abbrev    *table[HASHSIZE];
  80. char    *abbrev,
  81.     *phrase;
  82. {
  83.     register struct abbrev    *ap;
  84.  
  85.     ap = lookup_abbrev(table, abbrev);
  86.     if (ap == NULL) {
  87.         register unsigned int    h = hash(abbrev);
  88.  
  89.         ap = (struct abbrev *) emalloc(sizeof *ap);
  90.         ap->a_hash = h;
  91.         ap->a_abbrev = copystr(abbrev);
  92.         h %= HASHSIZE;
  93.         ap->a_next = table[h];
  94.         ap->a_cmdhook = NULL;
  95.         table[h] = ap;
  96.     } else
  97.         free((UnivPtr) ap->a_phrase);
  98.     ap->a_phrase = copystr(phrase);
  99. }
  100.  
  101. void
  102. AbbrevExpand()
  103. {
  104.     Bufpos    point;
  105.     char    wordbuf[100];
  106.     register char    *wp = wordbuf,
  107.             *cp;
  108.     register int    c;
  109.  
  110.     int    UC_count = 0;
  111.     struct abbrev    *ap;
  112.  
  113.     DOTsave(&point);
  114.     WITH_TABLE(curbuf->b_major)
  115.         b_word(1);
  116.         while (curchar < point.p_char && ismword(c = linebuf[curchar])) {
  117.             if (AutoCaseAbbrev) {
  118.                 if (jisupper(c)) {
  119.                     UC_count += 1;
  120.                     c = jtolower(c);
  121.                 }
  122.             }
  123.             *wp++ = c;
  124.             curchar += 1;
  125.         }
  126.         *wp = '\0';
  127.     END_TABLE();
  128.  
  129.     if ((ap = lookup_abbrev(A_tables[curbuf->b_major], wordbuf)) == NULL &&
  130.         (ap = lookup_abbrev(A_tables[GLOBAL], wordbuf)) == NULL) {
  131.         SetDot(&point);
  132.         return;
  133.     }
  134.     del_char(BACKWARD, (wp - wordbuf), NO);
  135.  
  136.     for (cp = ap->a_phrase; (c = *cp) != '\0'; ) {
  137.         if (AutoCaseAbbrev) {
  138.             insert_c(jislower(c) && UC_count &&
  139.                    (cp == ap->a_phrase || (UC_count > 1 && (cp[-1] == ' '))) ?
  140.                 CharUpcase(c) : c, 1);
  141.         } else
  142.             insert_c(c, 1);
  143.         cp += 1;
  144.     }
  145.     if (ap->a_cmdhook != NULL)
  146.         ExecCmd(ap->a_cmdhook);
  147. }
  148.  
  149. private char    *mode_names[NMAJORS + 1] = {
  150.     "Fundamental Mode",
  151.     "Text Mode",
  152.     "C Mode",
  153. #ifdef    LISP
  154.     "Lisp Mode",
  155. #endif
  156.     "Global"
  157. };
  158.  
  159. private void
  160. save_abbrevs(file)
  161. char    *file;
  162. {
  163.     File    *fp;
  164.     struct abbrev    *ap,
  165.             **tp;
  166.     char    buf[LBSIZE];
  167.     int    i,
  168.         count = 0;
  169.  
  170.     fp = open_file(file, buf, F_WRITE, YES, YES);
  171.     for (i = 0; i <= GLOBAL; i++) {
  172.         fwritef(fp, "------%s abbrevs------\n", mode_names[i]);
  173.         for (tp = A_tables[i]; tp < &A_tables[i][HASHSIZE]; tp++)
  174.             for (ap = *tp; ap; ap = ap->a_next) {
  175.                 fwritef(fp, "%s:%s\n",
  176.                     ap->a_abbrev,
  177.                     ap->a_phrase);
  178.                 count += 1;
  179.             }
  180.     }
  181.     f_close(fp);
  182.     add_mess(" %d written.", count);
  183. }
  184.  
  185. private void
  186. rest_abbrevs(file)
  187. char    *file;
  188. {
  189.     int    mode = -1,    /* Will be ++'d immediately */
  190.         lnum = 0;
  191.     char    *phrase_p;
  192.     File    *fp;
  193.     char    buf[LBSIZE];
  194.  
  195.     fp = open_file(file, buf, F_READ, YES, YES);
  196.     while (mode <= GLOBAL) {
  197.         if (f_gets(fp, genbuf, (size_t) LBSIZE) || genbuf[0] == '\0')
  198.             break;
  199.         lnum += 1;
  200.         if (strncmp(genbuf, "------", (size_t)6) == 0) {
  201.             mode += 1;
  202.             continue;
  203.         }
  204.         if (mode == -1 || (phrase_p = strchr(genbuf, ':')) == NULL)
  205.             complain("Abbrev. format error, line %d.", file, lnum);
  206.         *phrase_p++ = '\0';    /* Null terminate the abbrev. */
  207.         define(A_tables[mode], genbuf, phrase_p);
  208.     }
  209.     f_close(fp);
  210.     message(NullStr);
  211. }
  212.  
  213. void
  214. DefGAbbrev()
  215. {
  216.     def_abbrev(A_tables[GLOBAL]);
  217. }
  218.  
  219. void
  220. DefMAbbrev()
  221. {
  222.     def_abbrev(A_tables[curbuf->b_major]);
  223. }
  224.  
  225. void
  226. SaveAbbrevs()
  227. {
  228.     char    filebuf[FILESIZE];
  229.  
  230.     save_abbrevs(ask_file((char *)NULL, (char *)NULL, filebuf));
  231. }
  232.  
  233. void
  234. RestAbbrevs()
  235. {
  236.     char    filebuf[FILESIZE];
  237.  
  238.     rest_abbrevs(ask_file((char *)NULL, (char *)NULL, filebuf));
  239. }
  240.  
  241. void
  242. EditAbbrevs()
  243. {
  244.     char    *tname = "jove_wam.$$$",
  245.         *EditName = "Abbreviation Edit";
  246.     Buffer    *obuf = curbuf,
  247.         *ebuf;
  248.  
  249.     if ((ebuf = buf_exists(EditName)) != NULL) {
  250.         if (ebuf->b_type != B_SCRATCH)
  251.             confirm("Over-write buffer %b? ", ebuf);
  252.     }
  253.     SetBuf(ebuf = do_select(curwind, EditName));
  254.     ebuf->b_type = B_SCRATCH;
  255.     initlist(ebuf);
  256.     /* Empty buffer.  Save the definitions to a tmp file
  257.        and read them into this buffer so we can edit them. */
  258.     save_abbrevs(tname);
  259.     read_file(tname, NO);
  260.     message("[Edit definitions and then type C-X C-C]");
  261.     Recur();        /* We edit them ... now */
  262.     /* RESetBuf in case we deleted the buffer while we were editing. */
  263.     SetBuf(ebuf = do_select(curwind, EditName));
  264.     if (IsModified(ebuf)) {
  265.         SetBuf(ebuf);
  266.         file_write(tname, NO);
  267.         rest_abbrevs(tname);
  268.     }
  269.     (void) unlink(tname);
  270.     SetBuf(do_select(curwind, obuf->b_name));
  271. }
  272.  
  273. void
  274. BindMtoW()
  275. {
  276.     struct abbrev    *ap;
  277.     char    *word;
  278.     data_obj    *hook;
  279.  
  280.     word = ask((char *)NULL, "Word: ");
  281.  
  282.     if ((ap = lookup_abbrev(A_tables[curbuf->b_major], word)) == NULL &&
  283.         (ap = lookup_abbrev(A_tables[GLOBAL], word)) == NULL)
  284.         complain("%s: unknown abbrev.", word);
  285.  
  286.     hook = findmac("Macro: ");
  287.     if (hook == NULL)
  288.         complain("[Undefined macro]");
  289.     ap->a_cmdhook = hook;
  290. }
  291.  
  292. #endif    /* ABBREV */
  293.